Zavarujte svoje Django REST Framework API-je z robustno avtentikacijo. Primerjajte avtentikacijo z žetoni in implementacijo JWT (JSON Web Token), vključno s praktičnimi primeri kode in najboljšimi praksami.
Python DRF Avtentikacija: Implementacija žetonov (Token) proti JWT za robustne API-je
Zavarovanje vaših API-jev je najpomembnejše. Pri gradnji API-jev s Pythonom in Django REST Framework (DRF) imate na voljo več možnosti avtentikacije. Ta članek se poglablja v dve priljubljeni metodi: avtentikacija z žetoni (Token) in avtentikacija JWT (JSON Web Token), primerja njune prednosti in slabosti ter ponuja praktične primere implementacije.
Razumevanje avtentikacije v API-jih
Avtentikacija je postopek preverjanja identitete uporabnika ali aplikacije, ki dostopa do vašega API-ja. Dobro implementiran sistem avtentikacije zagotavlja, da lahko samo pooblaščeni subjekti dostopajo do zaščitenih virov. V kontekstu RESTful API-jev avtentikacija običajno vključuje pošiljanje poverilnic (npr. uporabniško ime in geslo) z vsako zahtevo. Strežnik nato preveri te poverilnice in, če so veljavne, odobri dostop.
Avtentikacija z žetoni (Token)
Avtentikacija z žetoni je preprost in enostaven mehanizem. Ko se uporabnik uspešno prijavi, strežnik ustvari edinstven, naključen žeton in ga shrani v bazo podatkov ter ga poveže z uporabnikom. Odjemalec nato pošlje ta žeton v glavi 'Authorization' naslednjih zahtev. Strežnik pridobi žeton iz baze podatkov, preveri njegovo veljavnost in ustrezno odobri dostop.
Implementacija z DRF
DRF ponuja vgrajeno podporo za avtentikacijo z žetoni. Tukaj je opisano, kako jo implementirati:
- Namestite DRF in ga registrirajte v svojem projektu Django:
Najprej se prepričajte, da imate nameščen Django REST Framework:
pip install djangorestframework
Nato ga dodajte v `INSTALLED_APPS` v `settings.py`:
INSTALLED_APPS = [
...
'rest_framework',
]
- Dodajte shemo TokenAuthentication kot privzeti razred avtentikacije (neobvezno, vendar priporočeno):
V svoji datoteki `settings.py` dodajte naslednje:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
],
}
To bo globalno uporabilo avtentikacijo z žetoni v vašem API-ju. `SessionAuthentication` je vključen za interakcijo, ki temelji na brskalniku, vendar ga lahko odstranite za aplikacijo, ki jo poganja samo API.
- Ustvarite žeton za vsakega uporabnika:
Žetone lahko samodejno ustvarite za uporabnike ob ustvarjanju z dodajanjem obravnavalnika signala. Ustvarite datoteko z imenom `signals.py` v svoji aplikaciji (npr. `users/signals.py`):
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
Nato uvozite to datoteko `signals.py` v datoteki `users/apps.py` znotraj metode `ready` razreda konfiguracije vaše aplikacije. Primer za `users/apps.py`:
from django.apps import AppConfig
class UsersConfig(AppConfig):
default_auto_field = 'django.db.BigAutoField'
name = 'users'
def ready(self):
import users.signals
Zdaj lahko upravljate žetone z uporabo ukazne vrstice:
python manage.py drf_create_token <username>
- Implementirajte svoje poglede API:
Tukaj je preprost primer pogleda, ki zahteva avtentikacijo z žetoni:
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework.views import APIView
class ExampleView(APIView):
authentication_classes = [TokenAuthentication]
permission_classes = [permissions.IsAuthenticated]
def get(self, request):
content = {
'message': 'Hello, ' + request.user.username + '! You are authenticated.',
}
return Response(content)
V tem primeru `authentication_classes` določa, da je treba uporabiti avtentikacijo z žetoni, `permission_classes` pa določa, da lahko do pogleda dostopajo samo overjeni uporabniki.
- Vključite pogled API za prijavo:
Potrebujete tudi končno točko za ustvarjanje žetona ob uspešni prijavi:
from django.contrib.auth import authenticate
from rest_framework import status
from rest_framework.authtoken.models import Token
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
@api_view(['POST'])
@permission_classes([AllowAny])
def login(request):
username = request.data.get('username')
password = request.data.get('password')
user = authenticate(username=username, password=password)
if user:
token, _ = Token.objects.get_or_create(user=user)
return Response({'token': token.key})
else:
return Response({'error': 'Invalid Credentials'}, status=status.HTTP_401_UNAUTHORIZED)
Prednosti avtentikacije z žetoni
- Enostavnost: Enostavna za implementacijo in razumevanje.
- Brezstanjska: Vsaka zahteva za žeton vsebuje informacije, ki ji omogočajo, da je samostojna.
Slabosti avtentikacije z žetoni
- Odvisnost od baze podatkov: Za preverjanje veljavnosti žetona zahteva iskanje v bazi podatkov za vsako zahtevo. To lahko vpliva na učinkovitost delovanja, zlasti v večjem obsegu.
- Razveljavitev žetona: Razveljavitev žetona zahteva njegovo brisanje iz baze podatkov, kar je lahko zapleteno.
- Razširljivost: Morda ni najboljša rešitev za razširljivost za velike API-je z velikim prometom zaradi obremenitve baze podatkov.
JWT (JSON Web Token) Avtentikacija
JWT avtentikacija je sodobnejši in prefinjen pristop. JWT je kompakten, URL-varen JSON objekt, ki vsebuje trditve o uporabniku. Te trditve so digitalno podpisane z uporabo skrivnega ključa ali para javnega/zasebnega ključa. Ko se uporabnik prijavi, strežnik ustvari JWT in ga pošlje odjemalcu. Odjemalec nato vključi ta JWT v glavi 'Authorization' naslednjih zahtev. Strežnik lahko preveri podpis JWT brez dostopa do baze podatkov, zaradi česar je učinkovitejša in bolj razširljiva rešitev.
Implementacija z DRF
DRF ne ponuja vgrajene podpore za JWT avtentikacijo, vendar več odličnih knjižnic omogoča enostavno integracijo. Ena najbolj priljubljenih je `djangorestframework-simplejwt`.
- Namestite `djangorestframework-simplejwt`:
pip install djangorestframework-simplejwt
- Konfigurirajte nastavitve DRF:
V svoji datoteki `settings.py` dodajte naslednje:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'ALGORITHM': 'HS256',
'SIGNING_KEY': settings.SECRET_KEY,
'VERIFYING_KEY': None,
'AUTH_HEADER_TYPES': ('Bearer',),
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
}
Pojasnilo nastavitev:
- `ACCESS_TOKEN_LIFETIME`: Kako dolgo je veljaven dostopni žeton (primer, 5 minut).
- `REFRESH_TOKEN_LIFETIME`: Kako dolgo je veljaven osvežitveni žeton (primer, 1 dan). Osvežitveni žetoni se uporabljajo za pridobivanje novih dostopnih žetonov, ne da bi se moral uporabnik ponovno prijaviti.
- `ROTATE_REFRESH_TOKENS`: Ali naj se osvežitveni žetoni zavrtijo po vsaki uporabi.
- `BLACKLIST_AFTER_ROTATION`: Ali naj se stari osvežitveni žetoni po rotaciji umaknejo na črni seznam.
- `ALGORITHM`: Algoritem, ki se uporablja za podpisovanje JWT (HS256 je pogosta izbira).
- `SIGNING_KEY`: Skrivni ključ, ki se uporablja za podpisovanje JWT (običajno vaš Django SECRET_KEY).
- `AUTH_HEADER_TYPES`: Vrsta glave za avtorizacijo (običajno "Bearer").
- Vključite poglede API za prijavo in osvežitev žetonov:
`djangorestframework-simplejwt` ponuja poglede za pridobivanje in osveževanje žetonov. Vključite jih v svojo datoteko `urls.py`:
from django.urls import path
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
urlpatterns = [
path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
`TokenObtainPairView` zagotavlja dostopne in osvežitvene žetone po uspešni avtentikaciji. `TokenRefreshView` zagotavlja nov dostopni žeton, ko je na voljo veljaven osvežitveni žeton.
- Implementirajte svoje poglede API:
Tukaj je preprost primer pogleda, ki zahteva JWT avtentikacijo:
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_simplejwt.authentication import JWTAuthentication
class ExampleView(APIView):
authentication_classes = [JWTAuthentication]
permission_classes = [permissions.IsAuthenticated]
def get(self, request):
content = {
'message': 'Hello, ' + request.user.username + '! You are authenticated.',
}
return Response(content)
Podobno kot pri primeru avtentikacije z žetoni, `authentication_classes` določa, da je treba uporabiti JWT avtentikacijo, `permission_classes` pa omejuje dostop samo overjenim uporabnikom.
Prednosti JWT avtentikacije
- Razširljivost: Za preverjanje veljavnosti žetona ni potrebno iskanje v bazi podatkov, zaradi česar je bolj razširljiva.
- Brezstanjska: JWT vsebuje vse potrebne informacije za avtentikacijo.
- Standardizirana: JWT je široko sprejet standard, ki ga podpirajo številne knjižnice in platforme.
- Prijazna do mikroservisov: Primerna za arhitekture mikroservisov, saj lahko storitve neodvisno preverjajo JWT-je.
Slabosti JWT avtentikacije
- Zapletenost: Bolj zapletena za implementacijo kot avtentikacija z žetoni.
- Velikost žetona: JWT-ji so lahko večji od preprostih žetonov, kar lahko poveča uporabo pasovne širine.
- Razveljavitev žetona: Razveljavitev JWT je zahtevna. Ko je izdan, je veljaven do izteka roka. Rešitve vključujejo dajanje razveljavljenih žetonov na črni seznam, kar ponovno uvaja odvisnost od baze podatkov.
Strategije za razveljavitev žetonov
Obe metodi avtentikacije z žetoni in JWT zahtevata mehanizme za razveljavitev dostopa. Tukaj je opisano, kako lahko pristopite k razveljavitvi žetonov:
Razveljavitev avtentikacije z žetoni
Pri avtentikaciji z žetoni je razveljavitev enostavna: preprosto izbrišite žeton iz baze podatkov:
from rest_framework.authtoken.models import Token
try:
token = Token.objects.get(user=request.user)
token.delete()
except Token.DoesNotExist:
pass
Razveljavitev JWT avtentikacije
Razveljavitev JWT je bolj zapletena, ker je sam žeton samostojen in se ne zanaša na iskanje v bazi podatkov za preverjanje veljavnosti (sprva). Pogoste strategije vključujejo:
- Črni seznam žetonov: Shranite razveljavljene žetone na črni seznam (npr. v tabeli baze podatkov ali predpomnilniku Redis). Preden preverite veljavnost JWT, preverite, ali je na črnem seznamu. `djangorestframework-simplejwt` ponuja vgrajeno podporo za dajanje osvežitvenih žetonov na črni seznam.
- Kratki časi izteka roka veljavnosti: Uporabite kratke čase izteka roka veljavnosti dostopnih žetonov in se zanašajte na osvežitvene žetone za pogosto pridobivanje novih dostopnih žetonov. To omejuje možnost zlorabe ogroženega žetona.
- Zavrtite osvežitvene žetone: Zavrtite osvežitvene žetone po vsaki uporabi. To bo vsakič razveljavilo stare žetone in preprečilo krajo žetonov.
OAuth2 in OpenID Connect
Za bolj zapletene scenarije avtentikacije in avtorizacije razmislite o uporabi OAuth2 in OpenID Connect. Ti standardi zagotavljajo robusten okvir za prenos dostopa do virov brez deljenja poverilnic. OAuth2 je predvsem protokol za avtorizacijo, medtem ko OpenID Connect temelji na OAuth2 za zagotavljanje storitev avtentikacije. Več paketov Django, kot sta `django-oauth-toolkit` in `django-allauth`, olajša integracijo OAuth2 in OpenID Connect v vaše DRF API-je.
Primer scenarija: Uporabnik želi odobriti aplikaciji tretje osebe dostop do svojih podatkov, shranjenih v vašem API-ju. Z OAuth2 lahko uporabnik odobri aplikaciji brez deljenja svojega uporabniškega imena in gesla. Namesto tega aplikacija prejme dostopni žeton, ki ga lahko uporabi za dostop do uporabnikovih podatkov znotraj določenega obsega dovoljenj.
Izbira prave metode avtentikacije
Najboljša metoda avtentikacije je odvisna od vaših specifičnih zahtev:
- Enostavnost in hitrost implementacije: Avtentikacijo z žetoni je na splošno lažje implementirati sprva.
- Razširljivost: JWT avtentikacija je bolj razširljiva za API-je z velikim prometom.
- Varnostne zahteve: Razmislite o občutljivosti svojih podatkov in zahtevani stopnji varnosti. OAuth2/OpenID Connect ponujata najbolj robustne varnostne funkcije, vendar zahtevata bolj zapleteno implementacijo.
- Arhitektura mikroservisov: JWT-ji so primerni za mikroservise, saj lahko vsaka storitev neodvisno preverja žetone.
Najboljše prakse za avtentikacijo API-jev
- Uporabite HTTPS: Vedno uporabljajte HTTPS za šifriranje komunikacije med odjemalcem in strežnikom, s čimer zaščitite poverilnice pred prisluškovanjem.
- Varno shranjujte skrivnosti: Nikoli ne shranjujte skrivnih ključev ali gesel v navadnem besedilu. Uporabite spremenljivke okolja ali orodja za varno upravljanje konfiguracije.
- Implementirajte omejevanje hitrosti: Zaščitite svoj API pred zlorabo z implementacijo omejevanja hitrosti, da omejite število zahtev, ki jih lahko odjemalec izvede v danem časovnem obdobju.
- Preverite veljavnost vnosa: Temeljito preverite veljavnost vseh vhodnih podatkov, da preprečite napade z vbrizgavanjem.
- Spremljajte in beležite: Spremljajte svoj API za sumljive dejavnosti in beležite dogodke avtentikacije za namene revizije.
- Redno posodabljajte knjižnice: Posodabljajte svoje knjižnice Django, DRF in avtentikacije, da izkoristite varnostne popravke in izboljšave.
- Implementirajte CORS (Cross-Origin Resource Sharing): Pravilno konfigurirajte CORS, da dovolite samo zaupanja vrednim domenam dostop do vašega API-ja iz spletnih brskalnikov.
Zaključek
Izbira ustrezne metode avtentikacije je ključnega pomena za zavarovanje vaših DRF API-jev. Avtentikacija z žetoni ponuja preprostost, medtem ko JWT avtentikacija zagotavlja razširljivost in prilagodljivost. Razumevanje prednosti in slabosti vsake metode, skupaj z najboljšimi praksami za varnost API-jev, vam bo omogočilo izgradnjo robustnih in varnih API-jev, ki ščitijo vaše podatke in uporabnike.
Ne pozabite upoštevati svojih specifičnih potreb in izbrati rešitev, ki najbolje uravnoteži varnost, učinkovitost in enostavnost implementacije. Raziščite OAuth2 in OpenID Connect za bolj zapletene scenarije avtorizacije.